package org.epanetgrid.otimizacao.objfunctions;

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.epanetgrid.model.controls.ControlAction;
import org.epanetgrid.otimizacao.util.ExceptionUtils;
import org.epanetgrid.resultado.ResultadoSimulacao;


/**
 * Esta classe implementa a função objetivo que calcula o número de chavemantos, 
 * definido da seguinte forma: Chaveamento é a transição do estado desligado para 
 * o estado ligado em uma determinada bomba.
 * 
 * @author Cícero Alan Leite Cruz, alanlcruz@gmail.com, 09/01/2008
 *
 */
public class NumeroDeChaveamentosObjectiveFunction implements ObjectiveFunction<ResultadoSimulacao, Integer> {

	private static final long serialVersionUID = -311334636523462332L;

	/* (non-Javadoc)
	 * @see epanetgridag.otimizacao.objfunctions.ObjectiveFunction#evaluate(java.lang.Object)
	 */
	public Integer evaluate(ResultadoSimulacao resultado) {
		ExceptionUtils.checkNull(resultado, "O resultado para a função objetivo não pode ser nulo.");
		int numeroChaveamento = 0;

		TreeSet<ControlAction> escalonamento = new TreeSet<ControlAction>(resultado.getNetwork().getControls());
		Map<String, Set<ControlAction>> escalonamentoPorBomba = new TreeMap<String, Set<ControlAction>>();
		
		for (ControlAction action : escalonamento) {
			if ( escalonamentoPorBomba.get(action.getLinkID()) == null ) {
				escalonamentoPorBomba.put(action.getLinkID(), new TreeSet<ControlAction>());
			}
			escalonamentoPorBomba.get(action.getLinkID()).add(action);
		}		
		
		for (Set<ControlAction> esc : escalonamentoPorBomba.values()) {
			ControlAction anterior = null;
			for (ControlAction atual : esc) {
				if ( anterior != null && !anterior.state() && atual.state()) {
					numeroChaveamento++;
				}
				anterior = atual;
			}
		}
		
        return new Integer(numeroChaveamento);
	}

}
